/**
 * 判断是否是 Base64Image 字符串
 *
 * 如果是 则返回可以用的字符串
 *
 * 否则返回空
 * @param url 解析后的 base64 URL
 */
export const getBase64ImageString = (url: string): string | undefined => {
  const reg = /data:image\/.*;base64,(.*)/;
  const group = reg.exec(url);

  if (!group) {
    return;
  }
  return group[1];
};
/**
 * 判断是否是 Base64 Svg 字符串
 *
 * 如果是 则返回可以用的字符串
 *
 * 否则返回空
 * @param url 解析后的 base64 URL
 */
export const base64ToSvgString = (url: string): string | undefined => {
  const reg = /data:image\/svg\+xml;base64,(.*)/;
  const group = reg.exec(url);

  if (!group) {
    return;
  }
  return atob(group[1]);
};

/**
 *
 * @param img html的 img 标签
 * @param format 图片格式
 * @returns {string}
 */
export const getImageBase64URL = (
  img: HTMLImageElement,
  format: string = 'png',
) => {
  // 1. 创建canvas DOM元素，并设置其宽高和图片一样
  let canvas: HTMLCanvasElement | null = document.createElement('canvas');

  canvas.width = img.width;
  canvas.height = img.height;

  // 2. 使用画布画图
  const ctx = canvas.getContext('2d');
  ctx?.drawImage(img, 0, 0, img.width, img.height);

  // 3. 返回的是一串Base64编码的URL并指定格式
  const dataURL = canvas.toDataURL(`image/${format}`);
  canvas = null; // 释放
  return dataURL;
};

/**
 * 图片预览链接
 * https://cdn.nlark.com/yuque/0/2020/png/85716/1598714607638-61dcb106-9c1a-4fb5-b2b8-a178d3c4eb93.png
 */
export const errorBase64Url =
  '';

/**
 * 将 blob 转变为 base64 代码
 * @param blob
 */
export const blobToBase64 = (blob: Blob): Promise<string> =>
  new Promise((resolve, reject) => {
    const fileReader = new FileReader();
    fileReader.readAsDataURL(blob);
    fileReader.onload = (e) => {
      resolve(e?.target?.result as string);
    };
    fileReader.onerror = () => {
      reject(new Error('异常'));
    };
  });

/**
 * 将传入的 data:类型的数值 转成 Base64 类型的字符串
 * @param url
 */
export const ensureBase64DataURL = (url: string) => {
  const imageData = url.match(/data:(.+?)(;(.+))?,(.+)/i);

  // 确保传入的 data:类型的参数都是 base64 的
  if (imageData && imageData[3] !== 'base64') {
    // Solve for an NSURL bug that can't handle plaintext data: URLs
    const type = imageData[1];
    const data = decodeURIComponent(imageData[4]);
    const encodingMatch = imageData[3] && imageData[3].match(/^charset=(.*)/);
    let buffer: Buffer;

    if (encodingMatch) {
      // @ts-ignore
      buffer = Buffer.from(data, encodingMatch[1]);
    } else {
      buffer = Buffer.from(data);
    }

    return `data:${type};base64,${buffer.toString('base64')}`;
  }

  return url;
};

/**
 * 初始化图片的 URL
 * @param inputURL 输入 url
 */
export const initImageURL = (inputURL: string) => {
  if (!inputURL.startsWith('data:') && !inputURL.startsWith('http')) {
    throw Error(`不正确的图像网址:${inputURL}`);
  }
  const correctURL = ensureBase64DataURL(inputURL);
  const url = inputURL.startsWith('data:') ? correctURL : inputURL;
  // 如果 url 是 base64 的内联样式
  let base64;
  if (correctURL.startsWith('data:')) {
    base64 = getBase64ImageString(correctURL)!;
  } else {
    base64 = getBase64ImageString(errorBase64Url)!;
  }
  return { url, base64 };
};

/**
 * 等待图片完成加载
 * @param image
 */
export const waitForImageLoaded = (image: HTMLImageElement): Promise<void> =>
  new Promise((resolve, reject) => {
    image.onload = () => {
      resolve();
    };

    image.onerror = () => {
      reject(new Error('异常'));
    };
  });
